#include "EstrategiaRegistros.h"

EstrategiaRegistros::EstrategiaRegistros(Almacenamiento **persistencia,TipoAlmacenamiento tipo){
	this->posIni=0;
	this->offset=0;
	this->tipoA = tipo;
	
	this->persistencia = persistencia;
	
}
		
void EstrategiaRegistros::crear(TipoMemoria tipo, std::vector<Dato*> listaDatos, void* ptr){
	
	this->posIni= ptr;
	this->tipoMem= tipo;
	
	if (this->tipoA == BUFFER || this->tipoA == AMBOS)
		EstrategiaRegistros::cargaInicialB(listaDatos);
	if (this->tipoA == ARCHIVO || this->tipoA == AMBOS)
		EstrategiaRegistros::cargaInicialD(listaDatos);
	
}
		
void EstrategiaRegistros::insertar(Dato *nvoDato,int* nroComponente){

	Registro *reg;
	unsigned int tam= nvoDato->getTamanio(BINARIO);
	void* pos= (char*)Buffer::getInstance()->getPointer() + this->offset;
	if(this->tipoA==BUFFER || this->tipoA==AMBOS){	
		reg= new RegistroMemoria(this->tipoMem, tam,pos , nvoDato);
		this->persistencia[0]->getCompuesto()->addComponente(reg);
		reg->escribir(BINARIO);
     	*nroComponente = this->persistencia[0]->getCompuesto()->getCantidadComponentes() - 1;		
	}
	if(this->tipoA==ARCHIVO || this->tipoA==AMBOS){	
		FILE * fp;
		fp = (FILE*) this->posIni;
		fseek(fp,this->offset,SEEK_SET);
		reg= new RegistroDisco(this->tipoMem, tam, fp , nvoDato); 
		this->persistencia[1]->getCompuesto()->addComponente(reg);
		reg->escribir(BINARIO);	
     	*nroComponente = this->persistencia[1]->getCompuesto()->getCantidadComponentes() - 1;		
	}
	this->offset+=tam;
	
}
	

	
void EstrategiaRegistros::leer(Dato *daux){
	//daux lo unico que tiene es una una clave primaria!
	Compuesto *compuesto;
	unsigned int pos; 
	unsigned int tam;
	RegistroMemoria *rmaux;
	RegistroDisco *rdaux;
	
	if(this->tipoA==BUFFER || this->tipoA==AMBOS){	
		compuesto= this->persistencia[0]->getCompuesto();
		EstrategiaRegistros::ubicar(compuesto, daux, &pos, &tam, BINARIO);
		rmaux=(RegistroMemoria*)compuesto->getComponenteAt(pos);
		rmaux->leer(daux,BINARIO);
	}
	if(this->tipoA==ARCHIVO || this->tipoA==AMBOS){	
		compuesto=this->persistencia[1]->getCompuesto();
		EstrategiaRegistros::ubicar(compuesto, daux, &pos, &tam,BINARIO);
		rdaux=(RegistroDisco*)compuesto->getComponenteAt(pos);		
		rdaux->leer(daux,BINARIO);
	}

}

void EstrategiaRegistros::modificar(Dato *daux){

	unsigned int pos;
	unsigned int tam;
	void *posAux;
	ComponenteAlmacenamiento *reg;
	Compuesto *compuesto;
	
	
	if(this->tipoA==BUFFER || this->tipoA==AMBOS){	
		compuesto= this->persistencia[0]->getCompuesto();
		
		if (this->tipoMem== FIJA){
			ubicar(compuesto, daux,&pos, &tam, BINARIO);
			reg=compuesto->getComponenteAt(pos);
			reg->getAccesoDato(&posAux);//
			reg->escribir(posAux,daux,BINARIO);
		}
		else {
			this->eliminar(daux,0);
			this->insertar(daux,0);			
		}
		
		this->persistencia[0]->salvarTodo(BINARIO);//creo no va
	}
	if(this->tipoA==ARCHIVO || this->tipoA==AMBOS){	
		compuesto= this->persistencia[1]->getCompuesto();
		if (this->tipoMem== FIJA){
			ubicar(compuesto, daux,&pos, &tam,BINARIO);
			reg=compuesto->getComponenteAt(pos);
			reg->getAccesoDato(&posAux);//
			reg->escribir(posAux,daux,BINARIO);
		}
		else {
			this->eliminar(daux,0);
			this->insertar(daux,0);			
		}
		this->persistencia[1]->salvarTodo(BINARIO);//creo no va
	}
	
}
		
void EstrategiaRegistros::eliminar(Dato *daux, int nroComponente){

	int i;
	unsigned int pos;
	unsigned int tam;
	ComponenteAlmacenamiento *reg;
	Compuesto *compuesto;
	void *posAux;
	FILE *fp;
	
	
	if(this->tipoA==BUFFER || this->tipoA==AMBOS){	
		compuesto= this->persistencia[0]->getCompuesto();
		ubicar(compuesto,daux,&pos, &tam,BINARIO);
		reg = compuesto->getComponenteAt(pos);
		reg->borrar();
		compuesto ->deleteComponentAt(pos);
		for(i=pos;i<compuesto->getCantidadComponentes();i++){
			reg = compuesto ->getComponenteAt(i);
			reg->getAccesoDato(&posAux);//
			posAux = (char*) posAux -tam;
			reg->escribir(posAux,BINARIO);
		}
		
	}
	if(this->tipoA==ARCHIVO || this->tipoA==AMBOS){	
		compuesto= this->persistencia[1]->getCompuesto();
		ubicar(compuesto,daux,&pos, &tam,BINARIO);
		reg = compuesto->getComponenteAt(pos);
		reg->borrar();
		compuesto ->deleteComponentAt(pos);
		for(i=pos;i<compuesto->getCantidadComponentes();i++){
			reg = compuesto ->getComponenteAt(i);
			reg->getAccesoDato(&posAux);
			fp=(FILE*)posAux;
			fseek(fp,tam, SEEK_CUR);
			reg->escribir(posAux,BINARIO);
		}
	}
	this->offset-=tam;

}


void EstrategiaRegistros::cargaInicialB(std::vector<Dato*> listaDatos){

	RegistroMemoria *reg;
	unsigned int tam;
	void *pos= Buffer::getInstance()->getPointer();
	Compuesto *compuesto= this->persistencia[0]->getCompuesto();
	vector<Dato*>::iterator it;
	//(TipoMemoria tipo, int tamanio, void* accesoMemoria, dato
	for (it= listaDatos.begin(); it != listaDatos.end(); it++){
			tam= (*it)->getTamanio(BINARIO);
			reg= new RegistroMemoria(this->tipoMem, tam, pos, *it);
			pos= (char*)pos + tam ;
			this->offset+=tam;
			compuesto->addComponente(reg);
			// este reg lo debo  destruir aca??
	}
	this->persistencia[0]->salvarTodo(BINARIO);
}

void EstrategiaRegistros::cargaInicialD(std::vector<Dato*> listaDatos){
       
        RegistroDisco *reg;
        FILE *fp= (FILE*) this->posIni;
        unsigned int tam;
        Compuesto *compuesto= this->persistencia[1]->getCompuesto();
        vector<Dato*>::iterator it;
        //(TipoMemoria tipo, int tamanio, void* accesoMemoria, dato
        for (it= listaDatos.begin(); it != listaDatos.end(); it++){
                        tam= (*it)->getTamanio(BINARIO);
                        fseek(fp,this->offset,SEEK_SET);
                        reg= new RegistroDisco(this->tipoMem, tam,fp, *it);                       
                        this->offset+=tam;
                        compuesto->addComponente(reg);
        }
        this->persistencia[1]->salvarTodo(BINARIO);
}



EstrategiaRegistros::~EstrategiaRegistros(){
}
